﻿using System;
using CommonDomain;
using Sponsorship.Domain.Sponsors;

namespace Sponsorship.Domain.Payments
{
    /// <summary>
    /// Represents a payment in the Sponsorship domain. A <see cref="Payment"/> can be associated to a <see cref="Sponsor"/>.
    /// </summary>
    public class Payment : RelaxedAggregateBase
    {
        private Payment (Guid paymentId)
            : this (paymentId, null)
        {
            if (paymentId == Guid.Empty)
                throw new ArgumentException ("Id must not be empty.", "id");
        }

        // Infrastructure constructor used by AggregateFactory
        private Payment (Guid id, IMemento snapshot)
        {
            if (snapshot != null)
                throw new NotSupportedException ("This class does not support snapshots.");
            Id = id;
        }

        public void Associate (Guid sponsorId)
        {
            RaiseEvent (new AnonymousPaymentAssociated (Id, sponsorId));
        }

        public void Change (decimal amount, DateTime dateTime, BankInformation bankInformation, string text, string comment)
        {
            RaiseEvent (new PaymentChanged (Id, amount, dateTime, bankInformation, text, comment));
        }

        public void Delete()
        {
            RaiseEvent (new PaymentDeleted (Id));
        }

        public static Payment EnterAnonymousPayment (Guid paymentId, decimal amount, DateTime dateTime, BankInformation bankInformation, string text, string comment)
        {
            var payment = new Payment (paymentId);
            payment.RaiseEvent (new AnonymousPaymentEntered (paymentId, amount, dateTime, bankInformation, text, comment));
            return payment;
        }

        public static Payment EnterPayment (Guid paymentId, Guid sponsorId, decimal amount, DateTime dateTime, BankInformation bankInformation, string text, string comment)
        {
            var payment = new Payment (paymentId);
            payment.RaiseEvent (new PaymentEntered (paymentId, sponsorId, amount, dateTime, bankInformation, text, comment));
            return payment;
        }

        protected override IMemento GetSnapshot()
        {
            throw new NotSupportedException ("This class does not support snapshots.");
        }

        public void Disassociate()
        {
            RaiseEvent(new PaymentDisassociated(Id));
        }
    }
}